#if UNITY_EDITOR
using System.IO;
using System.Collections.Generic;
using Net.Helper;
using UnityEditor;
using UnityEngine;

namespace ActorSystem
{
    public class ActorGenerator : EditorWindow
    {
        public class Data
        {
            public string frameworkPath = "Assets/Plugins/GameDesigner";
            public string scriptPath = "Assets/Scripts";
            public string actorBaseClassName = "MyActorBase";
            public string actorClassName = "MyActor";
            public string actorPropertyClassName = "MyProperty";
            public string actorBuffClassName = "MyBuff";
            public string actorSkillClassName = "MySkill";
            public string actorSceneClassName = "MyScene";
            public string actorMonoSceneClassName = "MySceneComponent";
        }

        public enum GeneratorType
        {
            Actor,
            Property,
            Buff,
            Skill,
        }

        private Data data;
        private GeneratorType generatorType;
        private string generatorClassName;

        [MenuItem("GameDesigner/ActorSystem/Actor生成器", priority = 1)]
        static void ShowWindow()
        {
            var window = GetWindow<ActorGenerator>("Actor生成器");
            window.Show();
        }

        private void OnEnable()
        {
            LoadData();
        }

        private void OnDisable()
        {
            SaveData();
        }

        void LoadData()
        {
            data = PersistHelper.Deserialize<Data>("actorGeneratorData.json");
        }

        void SaveData()
        {
            PersistHelper.Serialize(data, "actorGeneratorData.json");
        }

        private void OnGUI()
        {
            EditorGUI.BeginChangeCheck();
            data.frameworkPath = EditorGUILayout.TextField("框架路径:", data.frameworkPath);
            data.scriptPath = EditorGUILayout.TextField("生成脚本路径:", data.scriptPath);
            data.actorBaseClassName = EditorGUILayout.TextField("ActorBase脚本类名:", data.actorBaseClassName);
            data.actorClassName = EditorGUILayout.TextField("Actor脚本类名:", data.actorClassName);
            data.actorPropertyClassName = EditorGUILayout.TextField("Property脚本类名:", data.actorPropertyClassName);
            data.actorBuffClassName = EditorGUILayout.TextField("Buff脚本类名:", data.actorBuffClassName);
            data.actorSkillClassName = EditorGUILayout.TextField("Skill脚本类名:", data.actorSkillClassName);
            data.actorSceneClassName = EditorGUILayout.TextField("Scene实体脚本类名:", data.actorSceneClassName);
            data.actorMonoSceneClassName = EditorGUILayout.TextField("Scene组件脚本类名:", data.actorMonoSceneClassName);
            if (GUILayout.Button("生成基础类型", GUILayout.Height(30f)))
                Generator();
            generatorClassName = EditorGUILayout.TextField("Actor类名:", generatorClassName);
            generatorType = (GeneratorType)EditorGUILayout.EnumPopup("Actor类型", generatorType);
            if (GUILayout.Button("生成新增类型", GUILayout.Height(30f)))
                Generator2();
            if (EditorGUI.EndChangeCheck())
                SaveData();
        }

        private void Generator()
        {
            var paths = new List<string>()
            {
                $"{data.scriptPath}/Actor/", $"{data.scriptPath}/Actor/Buffs/",
                $"{data.scriptPath}/Actor/Propertys/", $"{data.scriptPath}/Actor/Skills/",
            };

            foreach (var item in paths)
            {
                if (!Directory.Exists(item))
                    Directory.CreateDirectory(item);
                Debug.Log($"创建的脚本路径:{item}");
            }

            WriteCode("ActorBase_C", data.actorBaseClassName + "_C", string.Empty);
            WriteCode("ActorBase_S", data.actorBaseClassName + "_S", string.Empty);
            WriteCode("ActorBase_G", data.actorBaseClassName + "_G", string.Empty);

            WriteCode("Actor_C", data.actorClassName + "_C", string.Empty);
            WriteCode("Actor_S", data.actorClassName + "_S", string.Empty);
            WriteCode("Actor_G", data.actorClassName + "_G", string.Empty);

            WriteCode("ActorProperty_C", data.actorPropertyClassName + "_C", "Propertys");
            WriteCode("ActorProperty_S", data.actorPropertyClassName + "_S", "Propertys");
            WriteCode("ActorProperty_G", data.actorPropertyClassName + "_G", "Propertys");

            WriteCode("ActorBuff_C", data.actorBuffClassName + "_C", "Buffs");
            WriteCode("ActorBuff_S", data.actorBuffClassName + "_S", "Buffs");
            WriteCode("ActorBuff_G", data.actorBuffClassName + "_G", "Buffs");

            WriteCode("ActorSkill_C", data.actorSkillClassName + "_C", "Skills");
            WriteCode("ActorSkill_S", data.actorSkillClassName + "_S", "Skills");
            WriteCode("ActorSkill_G", data.actorSkillClassName + "_G", "Skills");

            WriteCode("ActorScene_C", data.actorSceneClassName + "_C", string.Empty);
            WriteCode("ActorScene_S", data.actorSceneClassName + "_S", string.Empty);
            WriteCode("ActorScene_G", data.actorSceneClassName + "_G", string.Empty);

            WriteCode("ActorSceneComponent", data.actorMonoSceneClassName, string.Empty);

            Debug.Log("生成成功!");

            AssetDatabase.Refresh();
        }

        private void Generator2()
        {
            var paths = new List<string>()
            {
                $"{data.scriptPath}/Actor/", $"{data.scriptPath}/Actor/Buffs/",
                $"{data.scriptPath}/Actor/Propertys/", $"{data.scriptPath}/Actor/Skills/",
            };

            foreach (var item in paths)
            {
                if (!Directory.Exists(item))
                    Directory.CreateDirectory(item);
                Debug.Log($"创建的脚本路径:{item}");
            }

            switch (generatorType)
            {
                case GeneratorType.Actor:
                    WriteCode2("Actor_C", generatorClassName + "_C", string.Empty);
                    WriteCode2("Actor_S", generatorClassName + "_S", string.Empty);
                    WriteCode2("Actor_G", generatorClassName + "_G", string.Empty);
                    break;
                case GeneratorType.Property:
                    WriteCode2("ActorProperty_C", generatorClassName + "_C", "Propertys");
                    WriteCode2("ActorProperty_S", generatorClassName + "_S", "Propertys");
                    WriteCode2("ActorProperty_G", generatorClassName + "_G", "Propertys");
                    break;
                case GeneratorType.Buff:
                    WriteCode2("ActorBuff_C", generatorClassName + "_C", "Buffs");
                    WriteCode2("ActorBuff_S", generatorClassName + "_S", "Buffs");
                    WriteCode2("ActorBuff_G", generatorClassName + "_G", "Buffs");
                    break;
                case GeneratorType.Skill:
                    WriteCode2("ActorSkill_C", generatorClassName + "_C", "Skills");
                    WriteCode2("ActorSkill_S", generatorClassName + "_S", "Skills");
                    WriteCode2("ActorSkill_G", generatorClassName + "_G", "Skills");
                    break;
            }

            Debug.Log("生成成功!");
            AssetDatabase.Refresh();
        }

        private void WriteCode(string scrTxt, string className, string extraPath)
        {
            var scrPath = $"{data.frameworkPath}/ActorSystem/Template/{scrTxt}.txt";
            var dstPath = $"{data.scriptPath}/Actor/{extraPath}/{className}.cs";
            var code = File.ReadAllText(scrPath);
            code = code.Replace("ACTORBASE_NAME", data.actorBaseClassName);
            code = code.Replace("ACTOR_NAME", data.actorClassName);
            code = code.Replace("ACTOR_PROPERTY_NAME", data.actorPropertyClassName);
            code = code.Replace("ACTOR_BUFF_NAME", data.actorBuffClassName);
            code = code.Replace("ACTOR_SKILL_NAME", data.actorSkillClassName);
            code = code.Replace("ACTOR_SCENE_NAME", data.actorSceneClassName);
            code = code.Replace("ACTOR_MONO_SCENE_NAME", data.actorMonoSceneClassName);
            if (!File.Exists(dstPath))
                File.WriteAllText(dstPath, code);
        }

        private void WriteCode2(string scrTxt, string className, string extraPath)
        {
            var scrPath = $"{data.frameworkPath}/ActorSystem/Template/{scrTxt}.txt";
            var dstPath = $"{data.scriptPath}/Actor/{extraPath}/{className}.cs";
            var code = File.ReadAllText(scrPath);
            code = code.Replace("ACTORBASE_NAME", data.actorBaseClassName);
            code = code.Replace("ACTOR_NAME", generatorType == GeneratorType.Actor ? generatorClassName : data.actorClassName);
            code = code.Replace("ACTOR_PROPERTY_NAME", generatorType == GeneratorType.Property ? generatorClassName : data.actorPropertyClassName);
            code = code.Replace("ACTOR_BUFF_NAME", generatorType == GeneratorType.Buff ? generatorClassName : data.actorBuffClassName);
            code = code.Replace("ACTOR_SKILL_NAME", generatorType == GeneratorType.Skill ? generatorClassName : data.actorSkillClassName);
            code = code.Replace("ACTOR_SCENE_NAME", data.actorSceneClassName);
            code = code.Replace("ACTOR_MONO_SCENE_NAME", data.actorMonoSceneClassName);
            if (!File.Exists(dstPath))
                File.WriteAllText(dstPath, code);
        }
    }
}
#endif